package ru.averta.notes.service.search;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.fedor.vectorhighlight.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import ru.averta.notes.domain.Site;
import ru.averta.notes.other.UtilsLucene;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * <code>HighlighterServiceImpl</code>
 *
 * @author fedor.belov (fedor.belov@mail.ru)
 *         Date: 22.09.11 15:34
 */

@Service
public class HighlighterServiceImpl implements HighlighterService {

    private FastVectorHighlighter highlighter = null;
    private FastVectorHighlighter titleHighlighter = null;
    private static final Logger logger = LoggerFactory.getLogger(HighlighterServiceImpl.class);

    @PostConstruct
    private void setUp() {
        FragListBuilder fragListBuilder = new SimpleFragListBuilder();
        FragListBuilder titleFragListBuilder = new SingleFragListBuilder();
        FragmentsBuilder fragmentsBuilder = new ScoreOrderFragmentsBuilder(new SimpleBoundaryScanner(256));
        highlighter = new FastVectorHighlighter(true, true, fragListBuilder, fragmentsBuilder);
        titleHighlighter = new FastVectorHighlighter(true, true, titleFragListBuilder, fragmentsBuilder);
    }

    @Override
    public FieldQuery getFieldQuery(Query query) {
        return highlighter.getFieldQuery(query);
    }

    @Override
    public String getHighlightedContent(Site site, FieldQuery query, IndexReader indexReader, Integer docId) {
        Map<String, String[]> lightsMap = new HashMap<String, String[]>();

        //TODO усложнить реализацию

        addBestFragments(lightsMap, query, indexReader, docId, UtilsLucene.FIELD_MARK_CONTENT);
        addBestFragments(lightsMap, query, indexReader, docId, UtilsLucene.FIELD_MARK_COMMENT);
        addBestFragments(lightsMap, query, indexReader, docId, UtilsLucene.FIELD_IMPORTANT_SEARCH_CONTENT);
        addBestFragments(lightsMap, query, indexReader, docId, UtilsLucene.FIELD_FULL_SEARCH_CONTENT);

        List<String> result = new LinkedList<String>();

        String[] fields = new String[] {UtilsLucene.FIELD_MARK_COMMENT, UtilsLucene.FIELD_MARK_CONTENT, UtilsLucene.FIELD_IMPORTANT_SEARCH_CONTENT};
        for (String field : fields) {
            String[] lights = lightsMap.get(field);
            if (lights != null) {
                for (String light : lights) if (light != null && !"".equals(light)) result.add(light);
            }
        }

        if (result.isEmpty()) {
            String[] lights = lightsMap.get(UtilsLucene.FIELD_FULL_SEARCH_CONTENT);
            if (lights != null) {
                for (String light : lights) if (light != null && !"".equals(light)) result.add(light);
            }
        }

        return StringUtils.collectionToDelimitedString(result, ".. ");
    }

    @Override
    public String getHighlightedTitle(Site site, FieldQuery query, IndexReader indexReader, Integer docId) {
        try {
            return titleHighlighter.getBestFragment(query, indexReader, docId, UtilsLucene.FIELD_TITLE, Integer.MAX_VALUE);
        } catch (IOException e) {
            logger.error("Ошибка при выделении контента заголовка", e);
            return site.getTitle();
        }
    }


     private void addBestFragments(Map<String, String[]> map, FieldQuery query, IndexReader indexReader, Integer docId, String field) {
        try {
            map.put(field, highlighter.getBestFragments(query, indexReader, docId, field, 18, 5));
        } catch (IOException e) {
            logger.error("Ошибка при выделении найденного контента", e);
        }
    }

}
